perm filename A120.TEX[106,PHY] blob sn#848178 filedate 1987-11-04 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	\magnification\magstephalf
C00008 ENDMK
CāŠ—;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
  January\or February\or March\or April\or May\or June\or
  July\or August\or September\or October\or November\or December\fi
  \space\number\day, \number\year}
\baselineskip 14pt
\rm
\line{\sevenrm a120.tex[106,phy] \today\hfill}
\font\rmn=cmr9

\bigskip
\line{\bf Combining Files\hfill}

We are preparing a dictionary. We have a master text file of citations,
where each line consists of a word called the {\sl key}, left-justified
in a 30-character field, and a reference, left-justified in a
50-character field. When we have collected a number of new citations,
we sort them into alphabetical order by key, resulting in a new file to
be used for updating the old one. In both files, a~key of all~Zs serves
as a sentinel to mark the end.

There follows a program to combine the master and update files into a
new master file, preserving alphabetical order. This process is called
{\sl merging}.

\smallskip
{\obeylines\obeyspaces\let =\ \tt
        READLN(MASTER,MASTERKEY,MASTERCIT);
        READLN(UPDATE,UPDATEKEY,UPDATECIT);
        WHILE (MASTERKEY<SENTINEL) OR (UPDATEKEY<SENTINEL) DO
            BEGIN
            IF MASTERKEY<=UPDATEKEY THEN
                BEGIN
                WRITELN(NEWMASTER,MASTERKEY,MASTERCIT);
                READLN(MASTER,MASTERKEY,MASTERCIT)
                END
            ELSE
                BEGIN
                WRITELN(NEWMASTER,UPDATEKEY,UPDATECIT);
                READLN(UPDATE,UPDATEKEY,UPDATECIT)
                END
            END;
        WRITELN('ZZZ...Z','{\spa}...{\spa}')
}

\smallskip
A related problem is collation, where lines with equal keys are somehow
combined. For example, the personnel file has in each line fields for
employee number, name, and salary. The weekly file has a line for
each employee-day, with employee number and hours. Both are sorted
by employee number. The program prints for each line in the personnel
file a line that includes the total hours shown for that employee in the
weekly file. Weekly lines that correspond to no employee line are treated
as errors.

\vfill\eject

%\smallskip
{\obeylines\obeyspaces\let =\ \tt
        READLN(PERSONNEL,EMPNUM,SALARY);
        READLN(WEEKLY,WKEMPNUM,HOURS)
        SUMHRS:=0;
        WHILE (EMPNUM<SENTINEL) OR (WKEMPNUM<SENTINEL) DO
            IF WKEMPNUM<EMPNUM DO
               BEGIN
               WRITE('ERROR',WKEMPNUM,HOURS);
               READLN(WEEKLY,WKEMPNUM,HOURS)
               END
            ELSE IF WKEMPNUM=EMPNUM DO
               BEGIN
               SUMHRS:=SUMHRS+HOURS;
               READLN(WEEKLY,WKEMPNUM,HOURS)
               END
            ELSE
               BEGIN
               WRITE(REPORT,EMPNUM,SUMHRS,SUMHRS*SALARY);
               READLN(PERSONNEL,EMPNUM,SALARY)
               END
}

\smallskip
Check that the program never tries to read past the sentinel on either file,
nor to compute or print anything from a sentinel line.


\bigskip
\parindent0pt
\copyright 1987 Robert W. Floyd

First draft November 3, 1987.
%revised: May 6, 1987.
%subsequently revised.

\bye